package com.eastfair.venueservice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.eastfair.core.base.entity.SuperEntity;
import com.eastfair.core.context.ContextUtil;
import com.eastfair.core.exception.BizException;
import com.eastfair.core.utils.ConvertUtil;
import com.eastfair.venueservice.dao.ServiceCategoryMapper;
import com.eastfair.venueservice.dao.ServiceSpecsMapper;
import com.eastfair.venueservice.dto.*;
import com.eastfair.venueservice.entity.ServiceCategory;
import com.eastfair.venueservice.entity.ServiceInventory;
import com.eastfair.venueservice.entity.ServiceItem;
import com.eastfair.venueservice.entity.ServiceSpecs;
import com.eastfair.venueservice.enumeration.ServiceItemServiceStateEnum;
import com.eastfair.venueservice.exceptioncode.VenueServiceExceptionCode;
import com.eastfair.venueservice.service.ServiceInventoryService;
import com.eastfair.venueservice.service.ServiceItemService;
import com.eastfair.venueservice.service.ServiceSpecsService;
import com.eastfair.boot.service.SuperServiceImpl;

import com.eastfair.venueservice.vo.ServiceSpecsVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.eastfair.constant.BusinessConstant;
import com.eastfair.core.base.R;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

//import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 业务实现类
 * 服务规格
 * </p>
 *
 * @author lyw
 * @date 2022-07-13
 */
@Slf4j
@Service
//@DS("#thread.tenant")
public class ServiceSpecsServiceImpl extends SuperServiceImpl<ServiceSpecsMapper, ServiceSpecs> implements ServiceSpecsService {

    @Autowired
    private ServiceSpecsMapper serviceSpecsMapper;
    @Autowired
    private ServiceCategoryMapper serviceCategoryMapper;
    @Autowired
    private ServiceInventoryService serviceInventoryService;
    @Autowired
    private ServiceItemService serviceItemService;


    /**
     * 处理逻辑删除相关处理
     *
     * @param modelList 实体
     * @return 是否成功
     */
    @Override
    protected R<Boolean> handlerRemoveByIdsOfLogic(Collection<ServiceSpecs> modelList) {
        modelList.stream().forEach(s -> {
            s.setIsDeleted(BusinessConstant.YES);
        });
        // TODO: 2021/10/29 这里需要操作其他业务，如清空角色等
        return R.successDef();
    }

    @Override
    protected R<Boolean> handlerSave(ServiceSpecs model) {
        model.setProjectId(ContextUtil.getProjectId());
        model.setSubsystemId(ContextUtil.getSubSystemId());
        model.setTenantId(ContextUtil.getTenantId());
        return R.successDef();
    }

    /**
     * 保存服务规格
     * @param serviceSpecsDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveServiceSpecsInfo(ServiceSpecsDTO serviceSpecsDTO) {
        log.info("ServiceSpecsServiceImpl +++++ saveServiceSpecsInfo - 保存服务规格 params={}", JSONObject.toJSON(serviceSpecsDTO));
        ServiceCategory serviceCategory = serviceCategoryMapper.selectById(serviceSpecsDTO.getServiceCategoryId());
        if(StringUtils.isEmpty(serviceSpecsDTO.getSpecsCode())){
            if(Objects.nonNull(serviceCategory)){
                String s = String.valueOf((int) ((Math.random() * 9 + 1) * 100));
                String str = serviceCategory.getCategoryCode().substring(2, serviceCategory.getCategoryCode().length());
                serviceSpecsDTO.setSpecsCode("SP"+str+s);
            }
        }
        ServiceSpecs serviceSpecs = BeanUtil.toBean(serviceSpecsDTO, ServiceSpecs.class);
        return this.save(serviceSpecs);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveServiceSpecsInfoBatch(ServiceCategoryDTO serviceCategoryDTO) {
        // 判断是否有删除规格，且分类下服务存在已上架
        // 校验是否存在已上架的服务
        int count = serviceItemService.count(new QueryWrapper<ServiceItem>().lambda().eq(ServiceItem::getIsDeleted, BusinessConstant.NO)
                .eq(ServiceItem::getServiceCategoryId, serviceCategoryDTO.getId())
                .eq(ServiceItem::getServiceState, ServiceItemServiceStateEnum.ON_SHELVES));
        List<ServiceSpecs> list = list(new QueryWrapper<ServiceSpecs>().lambda()
                .eq(ServiceSpecs::getIsDeleted, BusinessConstant.NO)
                .eq(ServiceSpecs::getServiceCategoryId, serviceCategoryDTO.getId()));
        Map<String, ServiceSpecs> serviceSpecsMap = list.stream().collect(Collectors.toMap(ServiceSpecs::getSpecsCode, Function.identity()));
        if(CollectionUtils.isNotEmpty(serviceCategoryDTO.getServiceSpecsDTOS())){
            for (ServiceSpecsDTO serviceSpecsDTO : serviceCategoryDTO.getServiceSpecsDTOS()) {
                String specsCode = serviceSpecsDTO.getSpecsCode();
                Long serviceCategoryId = serviceSpecsDTO.getServiceCategoryId();
                serviceSpecsMap.remove(specsCode);
                // 查询该规格下的旧规格
                ServiceSpecs one = getOne(new QueryWrapper<ServiceSpecs>().lambda()
                        .eq(ServiceSpecs::getIsDeleted, BusinessConstant.NO)
                        .eq(ServiceSpecs::getSpecsCode, specsCode)
                        .eq(ServiceSpecs::getServiceCategoryId, serviceCategoryId));
                if(Objects.nonNull(one)){
                    one.setServiceSpecsName(serviceSpecsDTO.getServiceSpecsName());
                    one.setSort(serviceSpecsDTO.getSort());
                    updateById(one);
                }else {
                    saveServiceSpecsInfo(serviceSpecsDTO);
                }
            }
        }
        if (count > 0 && !serviceSpecsMap.isEmpty()) {
            throw BizException.wrap(VenueServiceExceptionCode.SERVICES_CATEGORY_SPECS_CANT_DELETE);
        }
        return true;
    }

    /**
     * 根据服务分类id查询规格
     * @param categoryId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ServiceSpecsVO> getServiceSpecsListByCategoryId(Long categoryId) {
        log.info("ServiceSpecsServiceImpl +++++ getServiceSpecsListByCategoryId - 根据服务分类id查询规格 params={}", categoryId);
        //查询展厅列表
        QueryWrapper<ServiceSpecs> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ServiceSpecs::getIsDeleted,BusinessConstant.DELETE_NO)
                .eq(Objects.nonNull(categoryId),ServiceSpecs::getServiceCategoryId,categoryId)
                .orderByAsc(ServiceSpecs::getSort);
        List<ServiceSpecs> list = this.list(queryWrapper);
        List<ServiceSpecsVO> serviceSpecsVOList = new ArrayList<>();
        // 查询规格库存
        for (ServiceSpecs serviceSpecs : list) {
            ServiceSpecsVO serviceSpecsVO = BeanUtil.copyProperties(serviceSpecs, ServiceSpecsVO.class);
            ServiceInventory serviceInventory = serviceInventoryService.getOne(new QueryWrapper<ServiceInventory>().lambda()
                    .eq(ServiceInventory::getIsDeleted, BusinessConstant.NO)
                    .eq(ServiceInventory::getServiceSpecsId, serviceSpecs.getId()).orderByDesc(ServiceInventory::getUpdateTime).last("limit 1"));
            if(Objects.nonNull(serviceInventory)){
                serviceSpecsVO.setInventoryNum(serviceInventory.getInventoryNum().setScale(0, RoundingMode.HALF_UP));
            }
            serviceSpecsVOList.add(serviceSpecsVO);
        }
        return serviceSpecsVOList;
    }

    /**
     * 删除规格
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean delServiceSpecsById(Long id) {
        log.info("ServiceSpecsServiceImpl +++++ delServiceSpecsById - 删除规格 params={}", id);
        ServiceSpecs specs = ServiceSpecs.builder()
                .id(id)
                .isDeleted(BusinessConstant.YES)
                .build();
        return this.updateById(specs);
    }

    @Override
    public List<ServiceSpecsVO> getServiceSpecsByIds(List<Long> ids) {
        if(CollectionUtils.isNotEmpty(ids)){
            List<ServiceSpecs> serviceSpecs = listByIds(ids);
            return ConvertUtil.convertList(serviceSpecs,ServiceSpecsVO.class);
        }else {
            return new ArrayList<>();
        }
    }
}
